/*
 * This program can be used to scan the contents of a disc to locate a
 *  deleted file, and then recover it to RAM::0.$.recover.
 *
 * Follow the instructions ...
 *
 * Note that !Style files seem to have the sequence [00]xV4 in bytes 3, 4, 5
 *  and 6.
 */

#include <stdio.h>
#include <string.h>

#include "kernel.h"
#include "swis.h"


#define  MAX_STRING          (256)
#define  MAX_SECTOR_SIZE    (4096)
#define  PART_SIZE           (256)


static int drive_num;
static int sector_size;
static int disc_size;
char string_to_look_for[MAX_STRING];

/* for recovery */
static int from_sector;
static int num_sectors;


static char buff[MAX_SECTOR_SIZE];



static _kernel_oserror * read_block (int blk)
{
    return _swix (ADFS_DiscOp, _IN(1)|_IN(2)|_IN(3)|_IN(4),
                      1,
                      (drive_num << 29) + blk * sector_size,
                      (int) buff,
                      sector_size);
}


static void out_part_block (int blk)
{
    int i;

    printf ("*** Block %d:\n", blk);
    for (i = 0; i < PART_SIZE; i++)
        printf("%c", buff[i]);
    printf(" ...\n");

    return;
}


void rescue ()
{
    int blk;
    FILE *f;

    printf ("Enter number of first sector to recover: ");
    scanf (" %d", &from_sector);
    printf ("Enter number of sectors to read: ");
    scanf (" %d", &num_sectors);
    printf ("Rescuing %d sectors starting at sector %d\n", num_sectors,
             from_sector);

    f = fopen ("RAM::0.$.recover", "wb");
    if (f == 0)
    {
        printf ("Cannot open RAM::0.$.recover\n");
        return;
    }

    for (blk = from_sector; blk < from_sector + num_sectors; blk++)
    {
        read_block (blk);
        fwrite (buff, 1, sector_size, f);
    }

    fclose (f);

    return;
}


int main ()
{
    int blk;
    _kernel_oserror *err;
    int len;
    int i;
    char ch;

    printf ("Enter drive number: ");
    scanf (" %d", &drive_num);
    printf ("    Drive number is %d\n", drive_num);

    printf ("Enter sector size: ");
    scanf (" %d", &sector_size);
    printf ("    Sector size is %d bytes\n", sector_size);

    do
    {
        printf ("Search (S) or rescue (R)? ");
        scanf (" %c", &ch);
    } while (ch != 'S' && ch != 'R');

    if (ch == 'R')
    {
        rescue ();
        return 0;
    }

    printf ("Enter disc size in sectors: ");
    scanf (" %d", &disc_size);
    printf (    "Disc size is %d sectors\n", disc_size);

    printf ("Enter string to look for, terminated by newline: ");
    ch = getc (stdin);
    gets (string_to_look_for);
    len = strlen (string_to_look_for);
    printf ("    Looking for '%s'\n", string_to_look_for);
   
    for (blk = 0; blk < disc_size; blk++)
    {
        if (blk%1000 == 0)
            printf ("        Block %d ...\n", blk);

        err = read_block (blk);

        if (err)
            printf ("blk = %d, err = '%s'\n", blk, err->errmess);
        else
        {
            i = 0;
            while (i < sector_size)
            {
                if (memcmp (buff+i, string_to_look_for, len) == 0)
                {
                    out_part_block (blk);
                    break;
                }
                i++;
            }
        }
    }

    return 0;
}


